﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlayerInterface;
using System.IO;

namespace ControllerLib
{


    struct BetterMap
    {
        public bool open;
        public int startDrt; //携带需要到达此处出发时应走的方向
        public int startJudge; //如果以此处作为目的地，则judge和的最小值

        public int? item; //该点有什么
        public bool player;//该点是否有玩家
        public int passJudge; //对该点的经过评估
        public int terminalJudge;//对该点的停留评估
        public int canBoomBox;//如果在该节点放炸弹可炸多少箱子
    }

    struct AskMap
    {
        public int fatherx, fathery; //父节点坐标
        public int howToTurn; //在这点应该向哪走
        public int G, H; //采用曼哈顿估算法
        public int? item; //该点有什么
        public bool player;//该点是否有玩家
        public int passJudge; //对该点的经过评估
    }






    class Controller : PlayerInterface.IControl
    {
        int playerIndex;
        int[] position;
        int? mapTemp; //暂存获取到的地图信息，-1表示不可用，0空地，1可炸，2不可炸，3炸弹，null表示查询非法
        int safeState = 0; //当前状态安全级别，0表示无任何危险，1表示可能受到炸弹的威胁，2表示需要躲开毒区，3表示立即躲开炸弹
        BetterMap[,] nearByMap = new BetterMap[5, 5]; //附近地图和全局地图
        AskMap[,] globalMap = new AskMap[10, 10];
        int[] minUnit = new int[4]; //附近最佳目的地的信息,startDrt,startJudge,x,y
        bool newInstruction = false, canTotalProcess = true, canJudge = true, canAStar = true, canDFS = true, firstRun = true, naviState = false, haveBoxNearBy, haveBoxGlobal = true;
        int stepCost = 1, maxCanBoomBox;
        float[,] myBoom = new float[2, 3]; //x,y,setTime
        float[,] otherBoom = new float[3, 3]; //x,y,setTime
        List<int> open = new List<int>(); //百位为x个位为y
        List<int> close = new List<int>();
        int naviGoalX, naviGoalY, naviLevel;//naviLevel表示当前导航优先级，0表示普通导航，1表示紧急导航（0-炸箱子）
        //在常规巡查中要用到的临时变量
        float rmt;
        int boxCheck, globalBoxX, globalBoxY, globalBoxMHT;
        int cantProcess = 0;




        //======================================================================================================================================辅助函数
        public void updateBoom(float nowTime) //检查炸弹是否过期
        {
            //writeLog("updateBoom");

            for (int i = 0; i < 2; i++)
            {
                if (myBoom[i, 2] != 0 && myBoom[i, 2] - nowTime > 3.5)
                {
                    writeLog("destroyMyBoom i=" + i + "x=" + myBoom[i, 0] + " y=" + myBoom[i, 1] + " setTime=" + myBoom[i, 2] + " nowTime" + nowTime);
                    myBoom[i, 2] = 0;
                }
            }
            for (int i = 0; i < 3; i++)
            {
                if (otherBoom[i, 2] != 0 && otherBoom[i, 2] - nowTime > 3.5)
                {
                    writeLog("destroyOtherBoom x=" + otherBoom[i, 0] + " y=" + otherBoom[i, 1] + " setTime=" + otherBoom[i, 2] + " nowTime" + nowTime);
                    otherBoom[i, 2] = 0;
                }
            }
            return;
        }
        public bool setNewBoom(float nowTime)
        {
            updateBoom(nowTime);
            for (int i = 0; i < 2; i++)
            {
                if (myBoom[i, 2] == 0)
                {
                    myBoom[i, 0] = position[0];
                    myBoom[i, 1] = position[1];
                    myBoom[i, 2] = nowTime;
                    writeLog("setNewBoom i=" + i + "x=" + myBoom[i, 0] + " y=" + myBoom[i, 1] + " setTime=" + myBoom[i, 2] + " nowTime=" + nowTime);
                    return true;
                }
            }
            writeLog("failToSetBoom");
            return false;
        }
        public void detectBoom(int x, int y, float nowTime)
        {
            updateBoom(nowTime);
            for (int i = 0; i < 3; i++)
            {
                if (otherBoom[i, 2] == 0)
                {
                    otherBoom[i, 0] = x;
                    otherBoom[i, 1] = y;
                    otherBoom[i, 2] = nowTime;
                }
            }
        } //不建议直接调用此函数
        public float isThatMyBoom(int x, int y, float nowTime) //查询是否是自己放置的炸弹，-1表示不是，否则返回此炸弹的剩余时间
        {
            updateBoom(nowTime);
            for (int i = 0; i < 2; i++)
            {
                if (myBoom[i, 0] == x && myBoom[i, 1] == y && myBoom[i, 2] != 0)
                {
                    writeLog("thatsMyBoom x=" + myBoom[i, 0] + " y=" + myBoom[i, 1] + " setTime=" + myBoom[i, 2] + " nowTime=" + nowTime);
                    return nowTime - myBoom[i, 2] + 3;
                }
                else if ((x == position[0] && y == position[1]) || Math.Abs(myBoom[i, 2] - nowTime) < 0.5)
                {
                    return 3;
                }
            }
            writeLog("notMyBoom");
            return -1;
        }
        public float thatBoom(int x, int y, float nowTime)
        {
            updateBoom(nowTime);
            for (int i = 0; i < 3; i++)
            {
                if (otherBoom[i, 2] != 0 && otherBoom[i, 0] == x && otherBoom[i, 1] == y)
                {
                    writeLog("knownOtherBoom");
                    return nowTime - otherBoom[i, 2] + 3;
                }
            }
            writeLog("unknownOtherBoom");
            detectBoom(x, y, nowTime);
            return 3;
        }


        public void writeLog(string x)
        {
            /*
            using (StreamWriter sw = new StreamWriter("log2.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToLongTimeString().ToString());
                sw.WriteLine(x);
            }
            */
        }

        public void setSafeState(int x)
        {
            if (safeState < x) safeState = x;
        }
        public string GetTeamName()
        {
            return "Cno Shabby AI 2";
        }
        //======================================================================================================================================辅助函数











        //======================================================================================================================================A Star导航
        public int sortF(int a, int b)
        {
            int x1, y1, x2, y2;
            x1 = a / 100;
            y1 = a % 100;
            x2 = b / 100;
            y2 = b % 100;
            if (globalMap[x1, y1].G + globalMap[x1, y1].passJudge + globalMap[x1, y1].H > globalMap[x2, y2].G + globalMap[x2, y2].passJudge + globalMap[x2, y2].H) return 1;
            else if (globalMap[x1, y1].G + globalMap[x1, y1].passJudge + globalMap[x1, y1].H < globalMap[x2, y2].G + globalMap[x2, y2].passJudge + globalMap[x2, y2].H) return -1;
            return 0;
        }
        public void globalJudge(int x, int y, ref IEntity entity)
        {

            Array.Clear(globalMap, 0, globalMap.Length);

            int passDangerBoom, passSafeBoom, passSafeArea, passDangerArea, cantGo, centerBoom, centerBox;
            maxCanBoomBox = 0;
            haveBoxGlobal = false;
            globalBoxMHT = 10000;

            //权重控制
            passSafeBoom = 30;
            passDangerBoom = 40;

            passSafeArea = 40;
            passDangerArea = 80;

            cantGo = 200;
            centerBoom = 50;
            centerBox = 60;
            for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++)
                {
                    //估算H
                    globalMap[i, j].H = Math.Abs(i - x) + Math.Abs(j - y);
                    //权重计算
                    globalMap[i, j].item = entity.GetMapType(i, j);
                    switch (globalMap[i, j].item)
                    {
                        case 0:
                            break;
                        case 1:
                            bool noByBoom = true;
                            int a, b;
                            for (int ix = 1; ix < 5; ix++)
                            {
                                switch (ix)
                                {
                                    case 1:
                                        a = i - 1;
                                        b = j;
                                        break;
                                    case 2:
                                        a = i + 1;
                                        b = j;
                                        break;
                                    case 3:
                                        a = i;
                                        b = j - 1;
                                        break;
                                    default:
                                        a = i;
                                        b = j + 1;
                                        break;
                                }
                                if (a < 0 || a > 9 || b < 0 || b > 9) continue;
                                if (globalMap[a, b].item == 3)
                                {
                                    noByBoom = false;
                                    break;
                                }
                            } //检查箱子周围是否已经存在炸弹
                            if (noByBoom)
                            {
                                haveBoxGlobal = true;
                                if (Math.Abs(position[0] - i) + Math.Abs(position[1] - j) < globalBoxMHT)
                                {
                                    globalBoxMHT = Math.Abs(position[0] - i) + Math.Abs(position[1] - j);
                                    globalBoxX = i;
                                    globalBoxY = j;
                                }
                            }
                            globalMap[i, j].passJudge += centerBox;
                            break;
                        case 3:
                            globalMap[i, j].passJudge += centerBoom; //炸弹中心加高
                            float isTMB = isThatMyBoom(i, j, entity.GetRemainingTime());
                            if (isTMB != -1)
                            {
                                //自己放的炸弹
                                if (entity.PlayerBuffing(playerIndex, 2) == true)
                                {
                                    //作为buf炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (i + k >= 0 && i + k < 10 && j + q >= 0 && j + q < 10)
                                            {
                                                if (isTMB > 1.5)
                                                {
                                                    globalMap[i + k, j + q].passJudge += passSafeBoom;
                                                }
                                                else
                                                {
                                                    globalMap[i + k, j + q].passJudge += passDangerBoom;
                                                }
                                            }
                                        }
                                }
                                else
                                {
                                    //作为普通炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (!(k + q == 1 || k + q == -1 || (k == 0 && q == 0))) continue;
                                            if (i + k >= 0 && i + k < 10 && j + q >= 0 && j + q < 10)
                                            {
                                                if (isTMB > 1.5)
                                                {
                                                    globalMap[i + k, j + q].passJudge += passSafeBoom;
                                                }
                                                else
                                                {
                                                    globalMap[i + k, j + q].passJudge += passDangerBoom;
                                                }
                                            }
                                        }
                                }
                            }
                            else
                            {
                                //其他玩家放的炸弹
                                bool hasBuf = false;
                                for (int iy = 1; iy < 5; iy++)
                                {
                                    if (iy == playerIndex) continue;
                                    if (entity.PlayerBuffing(iy, 2) == true)
                                    {
                                        hasBuf = true;
                                        break;
                                    }
                                }
                                if (hasBuf)
                                {
                                    //作为buf炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (i + k >= 0 && i + k < 10 && j + q >= 0 && j + q < 10)
                                            {
                                                globalMap[i + k, j + q].passJudge += passDangerBoom;
                                            }
                                        }
                                }
                                else
                                {
                                    //作为普通炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (k + q != 1 && k + q != -1 && !(k == 0 && q == 0)) continue;
                                            if (i + k >= 0 && i + k < 10 && j + q >= 0 && j + q < 10)
                                            {
                                                globalMap[i + k, j + q].passJudge += passDangerBoom;
                                            }
                                        }
                                }
                            }
                            //炸弹处理完毕
                            break;
                        default:
                            globalMap[i, j].passJudge += cantGo;
                            break;
                    }
                    //物体标记完成，开始毒区标记
                    if (entity.GetRemainingTime() < 30)
                    {
                        rmt = entity.GetRemainingTime();
                        if (rmt > 25)
                        {
                            if (i == 0 || i == 9 || j == 0 || j == 9)
                            {
                                if (rmt > 27)
                                {
                                    globalMap[i, j].passJudge += passSafeArea;
                                }
                                else
                                {
                                    globalMap[i, j].passJudge += passDangerArea;
                                }
                            }
                        }
                        else if (rmt > 15)
                        {
                            if (i == 1 || i == 8 || j == 1 || j == 8)
                            {
                                if (rmt > 17)
                                {
                                    globalMap[i, j].passJudge += passSafeArea;
                                }
                                else
                                {
                                    globalMap[i, j].passJudge += passDangerArea;
                                }
                            }
                        }
                        else if (rmt > 5)
                        {
                            if (i == 2 || i == 7 || j == 2 || j == 7)
                            {
                                if (rmt > 7)
                                {
                                    globalMap[i, j].passJudge += passSafeArea;
                                }
                                else
                                {
                                    globalMap[i, j].passJudge += passDangerArea;
                                }
                            }
                        }
                    }
                } //全局地图加权计算函数并估算H值
        }
        public int nextAStar(int x, int y, int targetx, int targety)
        {
            if (x == targetx && y == targety)
            {
                writeLog("A Star findTarget x=" + x + " y=" + y);
                int o = x, p = y, to, tp, judge = 0;
                while (!(o == position[0] && p == position[1]))
                {
                    judge += globalMap[o, p].passJudge + 1;
                    to = o;
                    tp = p;
                    o = globalMap[to, tp].fatherx;
                    p = globalMap[to, tp].fathery;
                    if (to - o == -1)
                    {
                        globalMap[o, p].howToTurn = 1;
                    }
                    else if (to - o == 1)
                    {
                        globalMap[o, p].howToTurn = 2;
                    }
                    else if (tp - p == -1)
                    {
                        globalMap[o, p].howToTurn = 3;
                    }
                    else if (tp - p == 1)
                    {
                        globalMap[o, p].howToTurn = 4;
                    }
                    writeLog("A Star writeNavi x=" + o + " y=" + p + " turn=" + globalMap[o, p].howToTurn);
                }
                return judge;
            }

            open.Remove(x * 100 + y);
            close.Add(x * 100 + y);
            int a, b;
            for (int i = 1; i < 5; i++)
            {
                switch (i)
                {
                    case 1:
                        a = x - 1;
                        b = y;
                        break;
                    case 2:
                        a = x + 1;
                        b = y;
                        break;
                    case 3:
                        a = x;
                        b = y - 1;
                        break;
                    default:
                        a = x;
                        b = y + 1;
                        break;
                }
                if (a >= 0 && a < 10 && b >= 0 && b < 10 && globalMap[a, b].item == 0 && !close.Contains(a * 100 + b))
                {
                    if (open.Contains(a * 100 + b))
                    {
                        if (globalMap[a, b].G + globalMap[a, b].passJudge > globalMap[x, y].G + globalMap[x, y].passJudge + 1)
                        {
                            globalMap[a, b].fatherx = x;
                            globalMap[a, b].fathery = y;
                            globalMap[a, b].G = globalMap[x, y].G + 1;
                        }
                    }
                    else
                    {
                        globalMap[a, b].fatherx = x;
                        globalMap[a, b].fathery = y;
                        globalMap[a, b].G = globalMap[x, y].G + 1;
                        open.Add(a * 100 + b);
                    }
                }
            } //四向扩散，试图将其标记为open
            //writeLog("A Star openCount=" + open.Count() + " closeCount="+close.Count());


            if (open.Count() == 0)
            {
                writeLog("A Star failToFindTarget");
                return -1;
            }
            else
            {
                open.Sort(sortF);
                //writeLog("A Star nextStep x=" + open.First() / 100 + " y=" + open.First() % 100 + " F=" + (globalMap[open.First() / 100, open.First() % 100].G + globalMap[open.First() / 100, open.First() % 100].H + globalMap[open.First() / 100, open.First() % 100].passJudge) + " G=" + globalMap[open.First() / 100, open.First() % 100].G + " H=" + globalMap[open.First() / 100, open.First() % 100].H + " judge=" + globalMap[open.First() / 100, open.First() % 100].passJudge);
                return nextAStar(open.First() / 100, open.First() % 100, targetx, targety);
            }

        }
        public int AStar(int x, int y, ref IEntity entity)
        {
            if (entity.IsMoving()) return -1;
            globalJudge(x, y, ref entity);
            open.Clear();
            close.Clear();
            globalMap[position[0], position[1]].G = 0;
            open.Add(position[0] * 100 + position[1]);
            return nextAStar(position[0], position[1], x, y);
        } //规划并存储路线之后返回对该路线的评估
        public void setNavi(int x, int y, int level, ref IEntity entity)
        {
            if (x == position[0] && y == position[1]) return;
            if ((naviState && naviLevel <= level) || !naviState) //导航优先级冲突检测
            {
                if (AStar(x, y, ref entity) != -1) //调用A Star规划路径
                {
                    writeLog("setNavi x=" + x + " y=" + y);
                    naviState = true;
                    naviGoalX = x;
                    naviGoalY = y;
                    naviLevel = level;
                }
                else
                {
                    writeLog("error:unavailable input terminal,original navi is forced to be cancel");
                    naviState = false;
                }
            }
        } //导航设置管控函数
          //======================================================================================================================================A Star导航












        //======================================================================================================================================附近最佳目的地查找
        public void stateJudge(ref IEntity entity) //环境探测与行动评估函数
        {
            position = entity.GetPosition();
            safeState = 0;
            Array.Clear(nearByMap, 0, nearByMap.Length);
            //writeLog("startForesee");
            for (int i = 1; i < 4; i++) for (int j = 1; j < 4; j++) //获取自己周围3x3网格信息
                {
                    //writeLog("i=" + i + " j=" + j);
                    if (position[0] + i - 2 < 0 || position[0] + i - 2 > 9 || position[1] + j - 2 < 0 || position[1] + j - 2 > 9)
                    {
                        mapTemp = -1;
                    }
                    else
                    {
                        mapTemp = entity.GetMapType(position[0] + i - 2, position[1] + j - 2);
                    }
                    nearByMap[i, j].item = mapTemp;
                    if (mapTemp == 3)
                    {
                        bool whoseBoom, myBuf = false, otBuf = false, myBoomTime = false;
                        if (isThatMyBoom(position[0] + i - 2, position[1] + j - 2, entity.GetRemainingTime()) != -1) whoseBoom = true;
                        else whoseBoom = false;
                        if (whoseBoom)
                        {
                            if (entity.PlayerBuffing(playerIndex, 2) == true) myBuf = true;
                            else myBuf = false;
                            if (isThatMyBoom(position[0] + i - 2, position[1] + j - 2, entity.GetRemainingTime()) > 1.5) myBoomTime = true;
                            else myBoomTime = false;
                        }
                        else
                        {
                            otBuf = false;
                            for (int iy = 1; iy < 5; iy++)
                            {
                                if (iy == playerIndex) continue;
                                if (entity.PlayerBuffing(iy, 2) == true)
                                {
                                    otBuf = true;
                                    break;
                                }
                            }
                        }
                        //信息收集完成
                        if (whoseBoom)
                        {
                            //自己的炸弹
                            if (myBuf || (i + j == 3 || i + j == 5 || ((i == 2 && j == 2) && !myBuf)))
                            {
                                //能炸到自己
                                if (myBoomTime)
                                {
                                    //时间充裕
                                    setSafeState(1);
                                }
                                else
                                {
                                    //时间紧迫
                                    setSafeState(3);
                                }
                            }

                        }
                        else
                        {
                            //别人的炸弹
                            if (otBuf)
                            {
                                //别人开了buf
                                setSafeState(3);
                            }
                            else
                            {
                                //别人没开buf
                                if (i + j == 3 || i + j == 5 || (i == 2 && j == 2))
                                {
                                    //能炸到自己
                                    setSafeState(3);
                                }
                            }
                        }


                    }
                    //writeLog("endBoomJudge");
                }
            //writeLog("poisonJudge");
            if (entity.GetRemainingTime() < 30) //是否需要跑毒
            {
                rmt = entity.GetRemainingTime();
                if (rmt > 26)
                {
                    if (position[0] >= 9 || position[0] <= 0 || position[1] >= 9 || position[1] <= 0)
                    {
                        setSafeState(2);
                    }
                }
                else if (rmt > 16)
                {
                    if (position[0] >= 8 || position[0] <= 1 || position[1] >= 8 || position[1] <= 1)
                    {
                        setSafeState(2);
                    }
                }
                else if (rmt > 6)
                {
                    if (position[0] >= 7 || position[0] <= 2 || position[1] >= 7 || position[1] <= 2)
                    {
                        setSafeState(2);
                    }
                }
            }
            //writeLog("endPoisonJudge");
        }
        public void calcJudge(ref IEntity entity) //地图加权计算函数
        {
            int passDangerBoom, passSafeBoom, passSafeArea, passDangerArea, terminalSafeBoom, ternimalSafArea, terminalBox, cantGo, centerBoom;
            rmt = entity.GetRemainingTime();
            maxCanBoomBox = 0;
            haveBoxNearBy = false;
            switch (safeState)
            {
                case 3:
                case 2:
                case 1:
                default:
                    passSafeBoom = 10; //经过炸弹
                    passDangerBoom = 60;

                    passSafeArea = 10; //经过毒区
                    passDangerArea = 40;

                    terminalSafeBoom = 190; //终点
                    ternimalSafArea = 150;
                    terminalBox = -20;

                    cantGo = 200; //综合性
                    centerBoom = 210;
                    break;
            } //权重控制
            for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++)
                {
                    //if (i > 0 && i < 4 && j > 0 && j < 4) continue;
                    //if (!(i > 0 && i < 4 && j > 0 && j < 4))
                    {
                        if (position[0] + i - 2 < 0 || position[0] + i - 2 > 9 || position[1] + j - 2 < 0 || position[1] + j - 2 > 9)
                        {
                            mapTemp = -1;
                        }
                        else
                        {
                            mapTemp = entity.GetMapType(position[0] + i - 2, position[1] + j - 2);
                        }
                        nearByMap[i, j].item = mapTemp;
                    }
                    switch (nearByMap[i, j].item)
                    {
                        case 0:
                            break;
                        case 1: //标记箱子
                            //writeLog("findBox i=" + i + " j=" + j);
                            haveBoxNearBy = true;
                            nearByMap[i, j].passJudge += cantGo;
                            bool noByBoom = true;
                            int a, b;
                            for (int ix = 1; ix < 5; ix++)
                            {
                                switch (ix)
                                {
                                    case 1:
                                        a = i - 1;
                                        b = j;
                                        break;
                                    case 2:
                                        a = i + 1;
                                        b = j;
                                        break;
                                    case 3:
                                        a = i;
                                        b = j - 1;
                                        break;
                                    default:
                                        a = i;
                                        b = j + 1;
                                        break;
                                }
                                if (a < 0 || a > 4 || b < 0 || b > 4) continue;
                                if (nearByMap[a, b].item == 3)
                                {
                                    //writeLog("box i=" + i + " j=" + j + " haveBoomIn x=" + a + " y=" + b);
                                    noByBoom = false;
                                    break;
                                }
                            } //检查箱子周围是否已经存在炸弹
                            if (noByBoom)
                            {
                                nearByMap[i, j].terminalJudge += cantGo;
                                //writeLog("findNoBoomBox i=" + i + " j=" + j);
                                for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                    {
                                        //writeLog("tryToMarkCanBoomBox x=" + (i + k) + " y=" + (j + q));
                                        if (k + q == -2 || k + q == 0 || k + q == 2) continue;
                                        if (i + k >= 0 && i + k < 5 && j + q >= 0 && j + q < 5 && nearByMap[i + k, j + q].item == 0)
                                        {
                                            //writeLog("addBoxNumber x=" + (i + k) + " y=" + (j + q));
                                            nearByMap[i + k, j + q].terminalJudge += terminalBox;
                                            nearByMap[i + k, j + q].canBoomBox++;
                                            if (maxCanBoomBox < nearByMap[i + k, j + q].canBoomBox) maxCanBoomBox = nearByMap[i + k, j + q].canBoomBox;
                                        }
                                    }
                            }
                            break;
                        case 3:
                            if (i > 0 && i < 4 && j > 0 && j < 4)
                            {
                                writeLog("calcJudge detectNewBoom in 4x4");
                                if (isThatMyBoom(position[0] + i - 2, position[1] + j - 2, rmt) == -1)
                                {
                                    thatBoom(position[0] + i - 2, position[1] + j - 2, rmt);
                                }
                            } //新发现的敌方炸弹
                            nearByMap[i, j].passJudge += centerBoom; //炸弹中心加高
                            nearByMap[i, j].terminalJudge += centerBoom;
                            float isTMB = isThatMyBoom(position[0] + i - 2, position[1] + j - 2, rmt);
                            writeLog("findBoom x=" + (position[0] + i - 2) + " y=" + (position[1] + j - 2) + " isTMB=" + isTMB);
                            if (isTMB != -1)
                            {
                                //自己放的炸弹
                                if (entity.PlayerBuffing(playerIndex, 2) == true)
                                {
                                    //作为buf炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (i + k >= 0 && i + k < 5 && j + q >= 0 && j + q < 5)
                                            {
                                                if (isTMB > 1.5)
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passSafeBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += terminalSafeBoom;
                                                }
                                                else
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passDangerBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                            }
                                        }
                                }
                                else
                                {
                                    //作为普通炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (!(k + q == 1 || k + q == -1 || (k == 0 && q == 0))) continue;
                                            if (i + k >= 0 && i + k < 5 && j + q >= 0 && j + q < 5)
                                            {
                                                if (isTMB > 1.5)
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passSafeBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += terminalSafeBoom;
                                                }
                                                else
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passDangerBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                            }
                                        }
                                }
                            }
                            else
                            {
                                //其他玩家放的炸弹
                                bool hasBuf = false, safeBoom;
                                for (int iy = 1; iy < 5; iy++)
                                {
                                    if (iy == playerIndex) continue;
                                    if (entity.PlayerBuffing(iy, 2) == true)
                                    {
                                        hasBuf = true;
                                        break;
                                    }
                                } //检查其他玩家是否开了buf
                                if (thatBoom(i, j, rmt) > 1.5) safeBoom = true;
                                else safeBoom = false;

                                if (hasBuf)
                                {
                                    //作为buf炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (i + k >= 0 && i + k < 5 && j + q >= 0 && j + q < 5)
                                            {
                                                if (safeBoom)
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passSafeBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                                else
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passDangerBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                            }
                                        }
                                }
                                else
                                {
                                    //作为普通炸弹标记
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (k + q != 1 && k + q != -1 && !(k == 0 && q == 0)) continue;
                                            if (i + k >= 0 && i + k < 5 && j + q >= 0 && j + q < 5)
                                            {
                                                if (safeBoom)
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passSafeBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                                else
                                                {
                                                    nearByMap[i + k, j + q].passJudge += passDangerBoom;
                                                    nearByMap[i + k, j + q].terminalJudge += cantGo;
                                                }
                                            }
                                        }
                                }
                            }
                            //炸弹处理完毕
                            break;
                        default:
                            nearByMap[i, j].passJudge += cantGo;
                            nearByMap[i, j].terminalJudge += cantGo;
                            break;
                    }
                    //物体标记完成，开始毒区标记
                    if (rmt < 30)
                    {
                        if (rmt > 25)
                        {
                            if (position[0] + i - 2 == 0 || position[0] + i - 2 == 9 || position[1] + j - 2 == 0 || position[1] + j - 2 == 9)
                            {
                                if (rmt > 27)
                                {
                                    nearByMap[i, j].passJudge += passSafeArea;
                                    nearByMap[i, j].terminalJudge += ternimalSafArea;
                                }
                                else
                                {
                                    nearByMap[i, j].passJudge += passDangerArea;
                                    nearByMap[i, j].terminalJudge += cantGo;
                                }
                            }
                        }
                        else if (rmt > 15)
                        {
                            if (position[0] + i - 2 == 1 || position[0] + i - 2 == 8 || position[1] + j - 2 == 1 || position[1] + j - 2 == 8)
                            {
                                if (rmt > 17)
                                {
                                    nearByMap[i, j].passJudge += passSafeArea;
                                    nearByMap[i, j].terminalJudge += ternimalSafArea;
                                }
                                else
                                {
                                    nearByMap[i, j].passJudge += passDangerArea;
                                    nearByMap[i, j].terminalJudge += cantGo;
                                }
                            }
                        }
                        else if (rmt > 5)
                        {
                            if (position[0] + i - 2 == 2 || position[0] + i - 2 == 7 || position[1] + j - 2 == 2 || position[1] + j - 2 == 7)
                            {
                                if (rmt > 7)
                                {
                                    nearByMap[i, j].passJudge += passSafeArea;
                                    nearByMap[i, j].terminalJudge += ternimalSafArea;
                                }
                                else
                                {
                                    nearByMap[i, j].passJudge += passDangerArea;
                                    nearByMap[i, j].terminalJudge += cantGo;
                                }
                            }
                        }
                    }
                }
            //writeLog("endCalcJudge");
            /*
            for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++)
                {
                    writeLog("judge i=" + i.ToString() + " j=" + j.ToString() + " mapTemp=" + nearByMap[i, j].item.ToString() + " passJudge=" + nearByMap[i, j].passJudge.ToString() + " terminalJudge=" + nearByMap[i, j].terminalJudge.ToString()+" canBoomBox="+nearByMap[i,j].canBoomBox.ToString());
                }
            */
        }
        public int DFS(int x, int y, int judge, int openDrt, int startDrt, int deepth)
        {
            //writeLog("DFS i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
            if (x < 0 || x > 4 || y < 0 || y > 4) //超出数组边界
            {
                //writeLog("DFS overEdge i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " deepth=" + deepth.ToString());
                return 0;
            }
            else
            {
                judge += nearByMap[x, y].passJudge;
            }
            if (deepth > 4 || judge >= 600) //路径过长
            {
                //writeLog("DFS overLoad i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " deepth=" + deepth.ToString());
                return 0;
            }


            if (openDrt != 0)
            {
                //writeLog("DFS simpleLoop i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
                if (nearByMap[x, y].open && judge >= nearByMap[x, y].startJudge)
                {
                    //writeLog("DFS fartherWay i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
                    return 0; //新路径更远
                }
                //writeLog("DFS i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
                if (judge + nearByMap[x, y].terminalJudge + deepth * stepCost < nearByMap[x, y].startJudge || nearByMap[x, y].open == false)
                {
                    nearByMap[x, y].startJudge = judge + nearByMap[x, y].terminalJudge + deepth * stepCost;
                    nearByMap[x, y].startDrt = startDrt;
                    nearByMap[x, y].open = true;
                    if (nearByMap[x, y].startJudge < minUnit[1])
                    {
                        minUnit[0] = startDrt;
                        minUnit[1] = nearByMap[x, y].startJudge;
                        minUnit[2] = x;
                        minUnit[3] = y;
                        writeLog("DFS minSet x=" + (x + position[0] - 2) + " y=" + (y + position[1] - 2) + " startJudge=" + minUnit[1].ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
                    }
                    //writeLog("DFS writeUnity i=" + x.ToString() + " j=" + y.ToString() + " judge=" + judge.ToString() + " opendrt=" + openDrt.ToString() + " startdrt=" + startDrt.ToString() + " deepth=" + deepth.ToString());
                }
                if (openDrt != 2) DFS(x - 1, y, judge, 1, startDrt, deepth + 1);
                if (openDrt != 1) DFS(x + 1, y, judge, 2, startDrt, deepth + 1);
                if (openDrt != 4) DFS(x, y - 1, judge, 3, startDrt, deepth + 1);
                if (openDrt != 3) DFS(x, y + 1, judge, 4, startDrt, deepth + 1);
            }
            else
            {
                //writeLog("DFS firstRun");
                DFS(x - 1, y, nearByMap[2, 2].passJudge, 1, 1, 1);
                DFS(x + 1, y, nearByMap[2, 2].passJudge, 2, 2, 1);
                DFS(x, y - 1, nearByMap[2, 2].passJudge, 3, 3, 1);
                DFS(x, y + 1, nearByMap[2, 2].passJudge, 4, 4, 1);
            }
            return 0;
        } //DFS最佳路径规划函数

        //======================================================================================================================================附近最佳目的地查找









        //======================================================================================================================================组合函数
        public void shabbyProcesser(ref IEntity entity) //就近寻路组合函数
        {
            writeLog("shabbyProcesser");
            if (entity.IsMoving()) return;
            //canProcess = false;
            //=======================================================================行动评估
            //writeLog("stateJudge");
            stateJudge(ref entity);
            writeLog(safeState.ToString());
            //writeLog("calcJudge");
            //=======================================================================地图加权
            calcJudge(ref entity);
            //=======================================================================DFS规划最佳路径
            minUnit[0] = 0;
            minUnit[1] = nearByMap[2, 2].terminalJudge;
            minUnit[2] = 2;
            minUnit[3] = 2;
            DFS(2, 2, 0, 0, 0, 0);
            //writeLog("endtDFS");
            //canProcess = true;
            if (minUnit[2] != 2 || minUnit[3] != 2)
            {
                if (safeState == 0) setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 0, ref entity);
                else setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 1, ref entity);
            }
            //writeLog("stopShabbyProcesser");
        }
        public void detectMap(ref IEntity entity) //仅寻路，除非出现意外
        {
            if (entity.IsMoving())
            {
                writeLog("returnMoving");
                return;
            }

            canJudge = false;
            //=======================================================================行动评估
            //writeLog("startStateJudge in detectMap");
            stateJudge(ref entity);
            //writeLog("endStateJudge in detectMap");
            writeLog(safeState.ToString());
            //=======================================================================地图加权
            calcJudge(ref entity);
            if (safeState != 0)
            {
                //writeLog("runDFS");
                minUnit[0] = 0;
                minUnit[1] = nearByMap[2, 2].terminalJudge;
                minUnit[2] = 2;
                minUnit[3] = 2;
                DFS(2, 2, 0, 0, 0, 0);
                newInstruction = true;
                if (minUnit[2] != 2 || minUnit[3] != 2)
                {
                    if (safeState == 0) setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 0, ref entity);
                    else setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 1, ref entity);
                }
            }
            if (naviState && safeState == 0 && naviLevel > 0) naviLevel = 0;
            canJudge = true;
            //writeLog("stopDetect");
        }


        public void escapePoisonArea(ref IEntity entity)
        {
            int minArea, maxArea, nearestX = 4, nearestY = 4, nearestJudge = 10000, judge;
            minArea = entity.GetCircle() + 1;
            maxArea = 9 - minArea;
            for (int i = minArea; i <= maxArea; i++) for (int j = minArea; j <= maxArea; j++)
                {
                    if (entity.GetMapType(i, j) == 0)
                    {
                        judge = AStar(i, j, ref entity);
                        if (judge < nearestJudge)
                        {
                            nearestX = i;
                            nearestY = j;
                            nearestJudge = judge;
                        }
                    }
                }
            setNavi(nearestX, nearestY, 1, ref entity);
        } //缩圈时计算最近的安全区方块并设置导航
        public bool escapeBoom(ref IEntity entity)
        {
            writeLog("startEscapeBoomJudge");
            position = entity.GetPosition();
            Array.Clear(nearByMap, 0, nearByMap.Length);
            nearByMap[2, 2].item = 3;
            calcJudge(ref entity);
            minUnit[0] = 0;
            minUnit[1] = 210;
            minUnit[2] = 2;
            minUnit[3] = 2;
            //writeLog("sendToDFS nowTJ=" + nearByMap[2, 2].terminalJudge);
            DFS(2, 2, 0, 0, 0, 0);
            if (minUnit[0] != 0 && nearByMap[minUnit[2], minUnit[3]].terminalJudge < 200)
            {
                writeLog("couldEscapeBoom");
                return true;
            }
            else
            {
                writeLog("cantEscapeBoom");
                return false;
            }
        } //预测自己放下炸弹之后能否逃跑
        //======================================================================================================================================组合函数

















        public void Update(IEntity entity)
        {
            //writeLog("useUpdate");
            //初始化与保护组件
            if (entity.IsMoving() || !canTotalProcess)
            {
                if (!canTotalProcess) cantProcess++;
                if (cantProcess > 3)
                {
                    cantProcess = 0;
                }
                else return;
            }
            position = entity.GetPosition();
            writeLog("position x=" + position[0].ToString() + " y=" + position[1].ToString());
            canTotalProcess = false;
            if (firstRun)
            {
                playerIndex = entity.GetIndex();
                firstRun = false;
                for (int i = 0; i < 2; i++)
                {
                    myBoom[i, 0] = 0;
                    myBoom[i, 1] = 0;
                    myBoom[i, 2] = 0;
                }
                shabbyProcesser(ref entity);
            }
            //补血
            if (entity.CanUpgrade() && (entity.GetHP() <= 70 || (entity.GetRemainingTime() < 2 && entity.GetHP() < 100)))
            {
                entity.BuffHP();
            }
            /*
            //DFS输出的第一次转向控制
            if (newInstruction && entity.IsMoving() == false && minUnit[0] != 0)
            {
                //if (!setAnotherBoom) setAnotherBoom = true;
                writeLog("move=" + minUnit[0].ToString());
                switch (minUnit[0])
                {
                    case 1:
                        entity.TurnWest();
                        entity.MoveWest();
                        break;
                    case 2:
                        entity.TurnEast();
                        entity.MoveEast();
                        break;
                    case 3:
                        entity.TurnSouth();
                        entity.MoveSouth();
                        break;
                    case 4:
                        entity.TurnNorth();
                        entity.MoveNorth();
                        break;
                    default:
                        break;
                }
                newInstruction = false;
            }
            */


            //缩圈警告
            if (entity.GetRemainingTime() < 33)
            {
                rmt = entity.GetRemainingTime();
                if (rmt > 25)
                {
                    if (position[0] < 1 || position[0] > 8 || position[1] < 1 || position[1] > 8)
                    {
                        escapePoisonArea(ref entity);
                    }
                }
                else if (rmt > 15)
                {
                    if (position[0] < 2 || position[0] > 7 || position[1] < 2 || position[1] > 7)
                    {
                        escapePoisonArea(ref entity);
                    }
                }
                else if (rmt > 5)
                {
                    if (position[0] < 3 || position[0] > 6 || position[1] < 3 || position[1] > 6)
                    {
                        escapePoisonArea(ref entity);
                    }
                }
            }

            //导航控制（取代了日常寻路）
            if (naviState)
            {
                writeLog("runNavi");
                if (position[0] == naviGoalX && position[1] == naviGoalY)
                {
                    naviState = false;
                    writeLog("Navi reachTarget");
                    shabbyProcesser(ref entity);
                } //到达目的地取消导航
                if (globalMap[position[0], position[1]].howToTurn == 0 && naviState)
                {
                    writeLog("Navi fixBrokenGuide");
                    setNavi(naviGoalX, naviGoalY, naviLevel, ref entity);
                } //路径断裂，重新规划路线
                if (entity.IsMoving() == false)
                {
                    writeLog("moveNavi=" + globalMap[position[0], position[1]].howToTurn);
                    switch (globalMap[position[0], position[1]].howToTurn)
                    {
                        case 1:
                            if (globalMap[position[0] - 1, position[1]].item == 0)
                            {
                                entity.TurnWest();
                                entity.MoveWest();
                            }
                            else
                            {
                                writeLog("Navi stucked");
                                naviState = false;
                                shabbyProcesser(ref entity);
                            }
                            break;
                        case 2:
                            if (globalMap[position[0] + 1, position[1]].item == 0)
                            {
                                entity.TurnEast();
                                entity.MoveEast();
                            }
                            else
                            {
                                writeLog("Navi stucked");
                                naviState = false;
                                shabbyProcesser(ref entity);
                            }
                            break;
                        case 3:
                            if (globalMap[position[0], position[1] - 1].item == 0)
                            {
                                entity.TurnSouth();
                                entity.MoveSouth();
                            }
                            else
                            {
                                writeLog("Navi stucked");
                                naviState = false;
                                shabbyProcesser(ref entity);
                            }
                            break;
                        case 4:
                            if (globalMap[position[0], position[1] + 1].item == 0)
                            {
                                entity.TurnNorth();
                                entity.MoveNorth();
                            }
                            else
                            {
                                writeLog("Navi stucked");
                                naviState = false;
                                shabbyProcesser(ref entity);
                            }
                            break;
                        default:
                            break;
                    }
                    newInstruction = false;
                } //读取导航路径信息并控制移动
                detectMap(ref entity); //危险检查
                if (naviLevel == 0)
                {
                    boxCheck = 0;
                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                        {
                            if (k + q == -2 || k + q == 0 || k + q == 2) continue;
                            if (naviGoalX + k >= 0 && naviGoalX + k < 10 && naviGoalY + q >= 0 && naviGoalY + q < 10 && nearByMap[naviGoalX + k, naviGoalY + q].item == 1) boxCheck++;
                        }
                    if (boxCheck < maxCanBoomBox)
                    {
                        naviState = false;
                        shabbyProcesser(ref entity);
                    }
                } //为炸箱子而去，检查目的地是否还有这么多箱子可炸
            }
            else
            {
                writeLog("noNavi");
                if (!entity.CanBomb())
                {
                    detectMap(ref entity);
                } //等待自己的上一个炸弹爆炸
                else
                {
                    shabbyProcesser(ref entity);
                    if (!haveBoxNearBy && haveBoxGlobal)
                    {
                        writeLog("notHaveBoxIn5x5,searchForGlobalBox");
                        globalJudge(0, 0, ref entity);
                        if (haveBoxGlobal)
                        {
                            int a, b;
                            for (int ix = 1; ix < 5; ix++)
                            {
                                switch (ix)
                                {
                                    case 1:
                                        a = globalBoxX - 1;
                                        b = globalBoxY;
                                        break;
                                    case 2:
                                        a = globalBoxX + 1;
                                        b = globalBoxY;
                                        break;
                                    case 3:
                                        a = globalBoxX;
                                        b = globalBoxY - 1;
                                        break;
                                    default:
                                        a = globalBoxX;
                                        b = globalBoxY + 1;
                                        break;
                                }
                                if (a < 0 || a > 9 || b < 0 || b > 9) continue;
                                if (globalMap[a, b].item == 0)
                                {
                                    setNavi(a, b, 0, ref entity);
                                    break;
                                }
                            }
                        }
                    } //当5x5没有箱子时检查全局
                }
            }






            //炸弹放置函数(炸箱子)
            if (nearByMap[1, 2].item == 1 || nearByMap[3, 2].item == 1 || nearByMap[2, 1].item == 1 || nearByMap[2, 3].item == 1)
            {
                if (nearByMap[2, 2].canBoomBox >= maxCanBoomBox)
                {
                    //writeLog("tryToSetBoom canBoomBox=" + nearByMap[2, 2].canBoomBox + " maxCanBoomBox=" + maxCanBoomBox);
                    if (entity.CanBomb() == true && escapeBoom(ref entity))
                    {
                        entity.SetBomb();
                        setNewBoom(entity.GetRemainingTime());
                        writeLog("setBoom box");
                        setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 1, ref entity);
                        //writeLog("can you see me");
                    }
                }
            }
            //炸弹放置函数(炸玩家)
            if ((!haveBoxGlobal || entity.GetRemainingTime() < 30) && escapeBoom(ref entity))
            {
                entity.SetBomb();
                setNewBoom(entity.GetRemainingTime());
                writeLog("setBoom enermy");
                setNavi(minUnit[2] + position[0] - 2, minUnit[3] + position[1] - 2, 1, ref entity);
            }





            cantProcess = 0;
            canTotalProcess = true;
            return;
        }
    }
}
